package com.zynn.api.yinian.zuul.config.jwt;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;

/**
 * @author jwt
 *
 * JWT工具类
 */
@Slf4j
public class JwtUtil {

    /**
     * JWT密钥
     */
    private static final String JWT_SECRET = "JWT_SECRET";

    /**
     * JWT主题
     */
    private static final String JWT_SUBJECT = "JWT_SUBJECT";

    /**
     * JWT用户信息的key
     */
    private static final String USER_INFO_KEY = "USER_INFO_KEY";

    /**
     * JWT用户信息中的用户id的key
     */
    private static final String LOGIN_USER_ID = "LOGIN_USER_ID";

    /**
     * 过期时间(毫秒)
     * private static final long EXPIRE_MILLI_SECOND = 7 * 24 * 60 * 60 * 1000;
     */
    private static final long EXPIRE_MILLI_SECOND = 7 * 24 * 60 * 60 * 1000;

    /**
     * 把Header中的jwt信息解析成JwtInfo对象
     *
     * @param request
     * @return 解析成功返回JwtInfo对象, 否则返回null
     */
    public static JwtUserInfo parseJWT(HttpServletRequest request) {
        try {
            String token = request.getHeader(USER_INFO_KEY);
            Claims claims = Jwts.parser()
                    .setSigningKey(JWT_SECRET)
                    .parseClaimsJws(token)
                    .getBody();
            JwtUserInfo jwtUserInfo = new JwtUserInfo();
            jwtUserInfo.setLoginUserId(Long.parseLong(String.valueOf(claims.get(LOGIN_USER_ID))));
            return jwtUserInfo;
        } catch (Exception e) {
            log.error("JwtUtil.parseJWT", e);
            return null;
        }
    }

    /**
     * 把登录用户id存储到响应的Header中
     *
     * @param loginUserId 登录用户id
     * @param response
     */
    public static String createJWT(Long loginUserId, HttpServletResponse response) {
        String token = Jwts.builder()
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRE_MILLI_SECOND))
                .setSubject(JWT_SUBJECT)
                .claim(LOGIN_USER_ID, loginUserId)
                .signWith(SignatureAlgorithm.HS256, JWT_SECRET)
                .compact();

        response.setHeader(USER_INFO_KEY, token);
        return token;
    }


    /**
     * 把Header中的jwt信息解析出来,返回jwt中的登录用户id
     *
     * @param request
     * @return 返回登录用户id, 解析异常返回null
     */
    public static Long getLoginUserId(HttpServletRequest request) {

        JwtUserInfo jwtUserInfo = parseJWT(request);
        if (jwtUserInfo == null) {
            return null;
        }
        return jwtUserInfo.getLoginUserId();
    }
}